#pragma once
#include "common.h"
#include "spinlock.h"
#include "queue_t.h"

enum spinlock_fiber_queue_name
{
	condition_variable_queue,
	scheduler_running_queue,
	chan_recv_queue,
	chan_blocking_fiber_queue,
};
template<int ID>
class spinlock_fiber_queue
{
public:
	typedef spinlock mutex_t;

	spinlock_fiber_queue()
	{

	}
	fiber::ptr_t front()
	{
		std::lock_guard<mutex_t> guard(mtx_);
		queue_item<ID>::ptr_t item = queue_.front();
		return std::dynamic_pointer_cast<fiber>(item);
	}
	void pop_front()
	{
		std::lock_guard<mutex_t> guard(mtx_);
		queue_.pop_front();
	}
	void push_back(fiber::ptr_t _fiber)
	{
		std::lock_guard<mutex_t> guard(mtx_);
		queue_.push_back(_fiber);
	}
	bool empty()
	{
		std::lock_guard<mutex_t> guard(mtx_);
		return queue_.empty();
	}
	std::size_t size()
	{
		return queue_.size();
	}
	bool exist(fiber::ptr_t _fiber)
	{
		std::lock_guard<mutex_t> guard(mtx_);
		return queue_.exist(_fiber);
	}
	void erase(fiber::ptr_t _fiber)
	{
		std::lock_guard<mutex_t> guard(mtx_);
		queue_.erase(_fiber);
	}
	void clear()
	{
		std::lock_guard<mutex_t> guard(mtx_);
		queue_.clear();
	}
	void swap(spinlock_fiber_queue<ID> &other)
	{
		std::lock_guard<mutex_t> guard(mtx_);
		std::lock_guard<mutex_t> guard2(other.mtx_);
		queue_.swap(other.queue_);
	}
	mutex_t &get_mutex()
	{
		return mtx_;
	}
private:
	mutex_t mtx_;
	queue_t<ID> queue_;
};